﻿#region Using Directives

    using System;
    using System.Linq;
    using System.Text;

    using Csla;
    using Csla.Data;
    using Csla.Server;
    using Csla.Reflection;

    using MarketPulse.BusinessLogic.Core;
    using MarketPulse.DataAccess;
    using MarketPulse.Reporting.Core;
    using MarketPulse.Reporting.Core.Criteria;

#endregion

namespace MarketPulse.DataAccess.Factory
{
    /// <summary>
    /// Factory class for producing ReportingLevelInfoLists
    /// </summary>
    public class ReportingLevelFactory : ObjectFactory
    {
        #region Methods

            #region Fetch Methods

                #region ReportingLevelInfoList

                    /// <summary>
                    /// Method used to fetch a read only list of read only ReportingLevel objects from the database based on the ClientGUID and ProfileGUID criteria supplied             
                    /// </summary>
                    /// <param name="criteria">The criteria object holding the ClientGUID and ProfileGUID used to retrieve the list</param>
                    /// <returns>A read only list of read only ReportingLevel objects retrieved from the database</returns>
                    public ReportingLevelInfoList FetchInfoList(ClientGUIDAndProfileGUIDCriteria criteria)
                    {
                        try
                        {
                            using (var manager = ContextManager<DataContextObjects.Production.MUM_dev>.GetManager(Database.BusinessSystem))
                            {
                                // Create an instance to return
                                var reportingLevelInfoList = (ReportingLevelInfoList)MethodCaller.CreateInstance(typeof(ReportingLevelInfoList));

                                // ReportingPeriodInfoList is a read-only collection,
                                // so typically, when the data access is implemented in
                                // DataPortal_Fetch within the business object, the
                                // private IsReadOnly property must be set false in order to 
                                // populate the collection.  Here, within a factory 
                                // , it isn't visible so one must resort to calling the 
                                // SetIsReadOnly method provided by our parent, ObjectFactory.
                                SetIsReadOnly(reportingLevelInfoList, false);

                                // Fetch the data from the database based on the criteria
                                var companySelectResult = manager.DataContext.UspCompanySelectByProfileGUIDAndClientGUID(criteria.ProfileGUID, criteria.ClientGUID);

                                foreach (DataContextObjects.Production.UspCompanySelectByProfileGUIDAndClientGUIDResult result in companySelectResult)
                                {
                                    ReportingLevelInfo reportingLevelInfo = (ReportingLevelInfo)MethodCaller.CreateInstance(typeof(ReportingLevelInfo));

                                    // Common properties inherited from MarketPulseBase<Branch>
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.GUIDProperty, result.CompanyGUID.Value);
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.ObsoleteProperty, result.Obsolete.Value);
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.InsertDateTimeProperty, (SmartDate)result.InsertDateTime);
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.InsertUserGUIDProperty, result.InsertUserGUID.Value);
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.UpdateDateTimeProperty, (SmartDate)result.UpdateDateTime);
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.UpdateUserGUIDProperty, result.UpdateUserGUID.Value);
                                    // Other properties                            
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.ParentReportingLevelGUIDProperty, result.ParentCompanyGUID);
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.NameProperty, result.CompanyName);
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.TypeProperty, ReportingLevelType.Company);

                                    // TODO: Maybe set a default 'Selected' to companies with no ParentCompanyGUID? But what if there are none, not a safe assumption

                                    //CheckRules(reportingPeriodInfo);

                                    // Make sure that CSLA knows this has changed since being instantiated
                                    MarkOld(reportingLevelInfo);

                                    // Add the item to the list
                                    reportingLevelInfoList.Add(reportingLevelInfo);
                                }

                                var branchSelectResult = manager.DataContext.UspBranchSelectByProfileGUIDAndClientGUID(criteria.ProfileGUID, criteria.ClientGUID);

                                foreach (DataContextObjects.Production.UspBranchSelectByProfileGUIDAndClientGUIDResult result in branchSelectResult)
                                {
                                    ReportingLevelInfo reportingLevelInfo = (ReportingLevelInfo)MethodCaller.CreateInstance(typeof(ReportingLevelInfo));

                                    // Common properties inherited from MarketPulseBase<Branch>
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.GUIDProperty, result.BranchGUID.Value);
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.ObsoleteProperty, result.Obsolete.Value);
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.InsertDateTimeProperty, (SmartDate)result.InsertDateTime);
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.InsertUserGUIDProperty, result.InsertUserGUID.Value);
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.UpdateDateTimeProperty, (SmartDate)result.UpdateDateTime);
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.UpdateUserGUIDProperty, result.UpdateUserGUID.Value);
                                    // Other properties                            
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.ParentReportingLevelGUIDProperty, result.CompanyGUID);
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.NameProperty, result.BranchName);
                                    LoadProperty(reportingLevelInfo, ReportingLevelInfo.TypeProperty, ReportingLevelType.Branch);

                                    //CheckRules(reportingPeriodInfo);

                                    // Make sure that CSLA knows this has changed since being instantiated
                                    MarkOld(reportingLevelInfo);

                                    // Add the item to the list
                                    reportingLevelInfoList.Add(reportingLevelInfo);
                                }

                                SetIsReadOnly(reportingLevelInfoList, true);

                                // Make sure that CSLA knows this has changed since being instantiated
                                MarkOld(reportingLevelInfoList);

                                return reportingLevelInfoList;
                            }
                        }
                        catch (InvalidOperationException ioe)
                        {
                            //TODO log exception appropriately before re throwing
                            throw ioe;
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }
                    }


                    ///// <summary>
                    ///// Method used to fetch a read only list of read only ReportingLevel objects from the database based on the ClientGUID 
                    ///// </summary>
                    ///// <param name="criteria">The criteria object holding the ClientGUID used to retrieve the list</param>
                    ///// <returns>A read only list of read only ReportingLevel objects retrieved from the database</returns>
                    //public ReportingLevelInfoList FetchInfoList(SingleCriteria<Guid> criteria)
                    //{
                    //    try
                    //    {
                    //        using (var manager = ContextManager<DataContextObjects.Production.MUM_dev>.GetManager(Database.BusinessSystem))
                    //        {
                    //            // Create an instance to return
                    //            var reportingLevelInfoList = (ReportingLevelInfoList)MethodCaller.CreateInstance(typeof(ReportingLevelInfoList));

                    //            // ReportingPeriodInfoList is a read-only collection,
                    //            // so typically, when the data access is implemented in
                    //            // DataPortal_Fetch within the business object, the
                    //            // private IsReadOnly property must be set false in order to 
                    //            // populate the collection.  Here, within a factory 
                    //            // , it isn't visible so one must resort to calling the 
                    //            // SetIsReadOnly method provided by our parent, ObjectFactory.
                    //            SetIsReadOnly(reportingLevelInfoList, false);

                    //            // Fetch the data from the database based on the criteria
                    //            var uspCompanySelectByClientGUIDResult = manager.DataContext.UspCompanySelectByClientGUID(criteria.Value);

                    //            foreach (DataContextObjects.Production.UspCompanySelectByClientGUIDResult result in uspCompanySelectByClientGUIDResult)
                    //            {
                    //                ReportingLevelInfo reportingLevelInfo = (ReportingLevelInfo)MethodCaller.CreateInstance(typeof(ReportingLevelInfo));

                    //                // Common properties inherited from MarketPulseBase<Branch>
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.GUIDProperty, result.CompanyGUID.Value);
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.ObsoleteProperty, result.Obsolete.Value);
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.InsertDateTimeProperty, (SmartDate)result.InsertDateTime);
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.InsertUserGUIDProperty, result.InsertUserGUID.Value);
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.UpdateDateTimeProperty, (SmartDate)result.UpdateDateTime);
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.UpdateUserGUIDProperty, result.UpdateUserGUID.Value);

                    //                // Other properties                            
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.ParentReportingLevelGUIDProperty, result.ParentCompanyGUID);
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.NameProperty, result.CompanyName);
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.TypeProperty, ReportingLevelType.Company);

                    //                // TODO: Maybe set a default 'Selected' to companies with no ParentCompanyGUID? But what if there are none, not a safe assumption

                    //                //CheckRules(reportingPeriodInfo);

                    //                // Make sure that CSLA knows this has changed since being instantiated
                    //                MarkOld(reportingLevelInfo);

                    //                // Add the item to the list
                    //                reportingLevelInfoList.Add(reportingLevelInfo);
                    //            }

                    //            //var branchSelectResult = managerMUM.DataContext.UspBranchSelectByClientGUIDAndCountryGUID(criteria.Value);
                    //            var uspBranchSelectByClientGUIDResult = manager.DataContext.UspBranchSelectByClientGUID(criteria.Value);

                    //            foreach (DataContextObjects.Production.UspBranchSelectByClientGUIDResult result in uspBranchSelectByClientGUIDResult)
                    //            {
                    //                ReportingLevelInfo reportingLevelInfo = (ReportingLevelInfo)MethodCaller.CreateInstance(typeof(ReportingLevelInfo));

                    //                // Common properties inherited from MarketPulseBase<Branch>
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.GUIDProperty, result.BranchGUID.Value);
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.ObsoleteProperty, result.Obsolete.Value);
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.InsertDateTimeProperty, (SmartDate)result.InsertDateTime);
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.InsertUserGUIDProperty, result.InsertUserGUID.Value);
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.UpdateDateTimeProperty, (SmartDate)result.UpdateDateTime);
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.UpdateUserGUIDProperty, result.UpdateUserGUID.Value);
                    //                // Other properties                            
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.ParentReportingLevelGUIDProperty, result.CompanyGUID);
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.NameProperty, result.BranchName);
                    //                LoadProperty(reportingLevelInfo, ReportingLevelInfo.TypeProperty, ReportingLevelType.Branch);

                    //                //CheckRules(reportingPeriodInfo);

                    //                // Make sure that CSLA knows this has changed since being instantiated
                    //                MarkOld(reportingLevelInfo);

                    //                // Add the item to the list
                    //                reportingLevelInfoList.Add(reportingLevelInfo);
                    //            }

                    //            SetIsReadOnly(reportingLevelInfoList, true);

                    //            // Make sure that CSLA knows this has changed since being instantiated
                    //            MarkOld(reportingLevelInfoList);

                    //            return reportingLevelInfoList;
                    //        }
                    //    }
                    //    catch (InvalidOperationException ioe)
                    //    {
                    //        //TODO log exception appropriately before re throwing
                    //        throw ioe;
                    //    }
                    //    catch (Exception ex)
                    //    {
                    //        throw ex;
                    //    }
                    //}

                #endregion

            #endregion

        #endregion

    }
}
